QT+OpenGL导入STL文件(二进制/ascll码格式),鼠标交互实现缩放旋转

您所在的位置:网站首页 qt opengl渲染 QT+OpenGL导入STL文件(二进制/ascll码格式),鼠标交互实现缩放旋转

QT+OpenGL导入STL文件(二进制/ascll码格式),鼠标交互实现缩放旋转

2024-07-14 05:38| 来源: 网络整理| 查看: 265

碎碎念

        由于课设和大创涉及到了模型的旋转,因此专门去学习了模型的导入,也是废了不少心思,现在总结一下两种格式的简单导入,以及对stl模型两种格式的简单介绍。网上有很多大佬都有详细的解答,结尾附上链接;在导入较大网格数的模型时发现qt不是运行不了就是加载时间很长,网上找了很多办法也没有解决,并且当面片数过高时,由于二进制文件的三角形面片数占4字节(最多65535个三角形),因此超出时便会报溢出异常。本人太菜不知道怎么解决,只好采取blender的精简修改器减少面片数,当然面片数过低模型精度会降低,希望有大佬能解答疑问。欢迎指正。

下面是效果图展示:

 (ps:模型来自Three D Scans)

1. stl格式介绍及导出

STL文件:STL文件是一种用许多空间小三角形面片逼近三维实体表面的数据模型,STL模型的数据通过给出组成三角形法向量的3个分量(用于确定三角面片的正反方向)及三角形的3个顶点坐标来实现,一个完整的STL文件记载了组成实体模型的所有三角形面片的法向量数据和顶点坐标数据信息。目前的STL文件格式包括二进制文件(BINARY)和文本文件(ASCII)两种。

1.1 ascll码格式

1.2 二进制格式

1.3 模型导出

模型可以自己在建模软件中制作或者去建模软件下载stl格式,这里以blender为例:

        1. 首先打开blender,点击你想要导出的物体,注意在OpenGL中为右手坐标系,z轴朝外,如果发现方向不对需要将模型导入建模软件中调整一下模型方向再导出;

导出模型时最好以模型原点为中心,旋转时将以模型中心旋转;

         2. 点击文件,导出,选择stl格式;导出模型时注意点击仅导出选中物体,可根据需要选择是否导出ascll码格式,默认导出二进制格式。

这样就成功导出stl模型文件了。

1.4 举例解释两种格式文件

以上方导出的正方体为例解释:

        显然正方体有六个面,每个面由两个等腰直角三角形拼接而成,故一共有2*6=12个三角形,即下图这样的三角形有12组 

下面使用二进制查看器查看机器码:(或者用qt的资源文件打开也可查看)

前八十字节记录了模型基本信息,即模型是从blender导出的;

紧接着四字节为三角形面片信息;

剩下对于每个三角形有3个四字节浮点数(面片法矢量),3个顶点坐标(每个坐标为4字节的三元组)最后两个字节描述三角形面片属性信息。即每个三角形占50字节(3*4 + 3*(3*4)=50)

 2 QOpenGLWidget类进行opengl绘图 基础准备 在qt中新建一个c++类,继承QWidget;接着在该类导入相应的头文件 #include #include #include #include #include #include #include #include #include #include 将demoOpenglWidget的继承类改为 class demoOpenglWidget : public QOpenGLWidget,public QOpenGLExtraFunctions

点击QOpenGLWidget头文件,找到下面三个函数进行重载:

protected: //建立OpenGL的资源和状态。在第一次调用resizeGL()或paintGL()之前调用一次 void initializeGL(); //设置OpenGL视口,投影等。每当调整Widget的大小时(第一次显示窗口Widget时会调用它,因为所有新创建Widget都会自动获得调整大小的事件) void resizeGL(int width, int height); //渲染OpenGL场景,需要更新Widget时就会调用 void paintGL();

demoOpenglWidget.h

#ifndef DEMOOPENGLWIDGET_H #define DEMOOPENGLWIDGET_H #include #include #include #include #include #include #include #include #include #include class demoOpenglWidget : public QOpenGLWidget,public QOpenGLExtraFunctions { Q_OBJECT public: explicit demoOpenglWidget(QWidget *parent = nullptr); ~demoOpenglWidget(); public: double rotate_y=0; double rotate_x=0; double rotate_z=0; protected: void initializeGL(); void resizeGL(int width, int height); void paintGL(); QVector loadAscllStl(QString filename,int ratio);//加载Ascll格式的stl文件 QVector loadBinStl(std::string filename, int ratio);//加载二进制格式的stl文件 void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void wheelEvent(QWheelEvent *event);//图片缩放功能 private: QVector vertices; QVector Position;//顶点位置 QVector Normal;//法向量 QOpenGLShaderProgram shaderprogram; QOpenGLVertexArrayObject VAO; QOpenGLBuffer VBO; //MVP QMatrix4x4 model; QMatrix4x4 view; QMatrix4x4 projection; // int verticesCnt; GLfloat xtrans,ytrans,ztrans; QVector2D mousePos; QQuaternion rotation; }; #endif // DEMOOPENGLWIDGET_H 在qt资源中导入顶点着色器、片段着色器,并重载initializeGL、resizeGL和paintGL。 //stl.vert #version 330 core layout (location = 0) in vec3 aPos; // 位置变量的属性位置值为 0 layout (location = 1) in vec3 aNormal; // 颜色变量的属性位置值为 1 uniform mat4 model; uniform mat4 view; uniform mat4 projection; out vec3 FragPos; out vec3 Normal; void main() { gl_Position = projection * view * model * vec4(aPos, 1.0); Normal = mat3(model) * aNormal;//用于旋转时,使得法向量一起改变 FragPos = vec3(model * vec4(aPos, 1.0)); } //stl.frag #version 330 core //layout( location = 0 ) out vec4 FragColor; out vec4 FragColor; uniform vec3 objectColor; uniform vec3 lightColor; in vec3 FragPos; in vec3 Normal; uniform vec3 lightPos; void main() { float ambientStrength = 0.1; vec3 ambient = ambientStrength * lightColor; vec3 norm = normalize(Normal); vec3 lightDir = normalize(lightPos - FragPos); float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = diff * lightColor; vec3 result = (ambient + diffuse) * objectColor; FragColor = vec4(result, 1.0); } //渲染OpenGL场景,widget需要更新时调用 void demoOpenglWidget::initializeGL() { this->initializeOpenGLFunctions(); shaderprogram.create(); //将着色器加载到shaderprogram小程序中(注意路径根据自己的路径名称修改) if(!shaderprogram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shaders/stl.vert")) qDebug()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3